//! 池化模块测试工具
//! 
//! 提供池化模块单元测试的通用工具和模拟对象

use crate::{Result, Error};
use crate::types::{Language, SandboxState, SandboxMetadata, PoolStats};
use crate::sandbox_manager::{Sandbox, LifecycleManager};
use crate::firecracker::snapshot::SnapshotManager;
use std::sync::Arc;
use std::time::{SystemTime, Instant, Duration};
use tokio::sync::Mutex;
use uuid::Uuid;

/// 创建测试用的沙箱
pub fn create_test_sandbox(language: Language, state: SandboxState) -> Sandbox {
    Sandbox {
        id: Uuid::new_v4(),
        metadata: SandboxMetadata {
            language: language.clone(),
            state,
            created_at: SystemTime::now(),
            last_used: Some(SystemTime::now()),
            usage_count: 0,
            version: "test".to_string(),
            resource_usage: Default::default(),
        },
        language_config: crate::types::LanguageConfig {
            language,
            runtime_version: "test".to_string(),
            image_name: "test-image".to_string(),
            memory_limit_mb: 512,
            cpu_limit_cores: 1,
            disk_limit_mb: 1024,
            network_enabled: true,
            environment_variables: std::collections::HashMap::new(),
            startup_command: vec!["test".to_string()],
            health_check_command: Some("test".to_string()),
            timeout_seconds: 300,
        },
    }
}

/// 创建测试用的生命周期管理器模拟
pub fn create_mock_lifecycle_manager() -> Arc<LifecycleManager> {
    Arc::new(LifecycleManager::new())
}

/// 创建测试用的快照管理器模拟
pub fn create_mock_snapshot_manager() -> Arc<Mutex<SnapshotManager>> {
    Arc::new(Mutex::new(SnapshotManager::new()))
}

/// 创建测试用的池配置
pub fn create_test_pool_config() -> crate::config::PoolConfig {
    crate::config::PoolConfig {
        // 冷池配置
        cold_pool_snapshot_count: 5,
        cold_pool_max_age_hours: 24,
        cold_pool_cleanup_interval_minutes: 60,
        
        // 温池配置
        warm_pool_min_size: 2,
        warm_pool_max_size: 10,
        warm_pool_target_size: 5,
        warm_pool_preheat_threshold: 0.7,
        warm_pool_warmup_timeout_seconds: 30,
        
        // 热池配置
        hot_pool_min_size: 1,
        hot_pool_max_size: 20,
        hot_pool_target_size: 5,
        hot_pool_max_idle_time_seconds: 600,
        hot_pool_maintenance_interval_seconds: 120,
        
        // 全局配置
        max_reuse_count: 50,
        max_sandbox_lifetime_seconds: 3600,
        resource_cleanup_threshold: 0.8,
        enable_metrics: true,
        metrics_collection_interval_seconds: 60,
    }
}

/// 等待异步操作完成的辅助函数
pub async fn wait_for_condition<F, Fut>(condition: F, timeout: Duration) -> bool 
where
    F: Fn() -> Fut,
    Fut: std::future::Future<Output = bool>,
{
    let start = Instant::now();
    while start.elapsed() < timeout {
        if condition().await {
            return true;
        }
        tokio::time::sleep(Duration::from_millis(10)).await;
    }
    false
}

/// 验证沙箱状态的辅助函数
pub fn assert_sandbox_valid(sandbox: &Sandbox, expected_language: &Language) {
    assert_eq!(sandbox.metadata.language, *expected_language);
    assert!(matches!(
        sandbox.metadata.state, 
        SandboxState::Running | SandboxState::Starting
    ));
    assert!(sandbox.metadata.created_at <= SystemTime::now());
}

/// 验证池统计信息的辅助函数
pub fn assert_pool_stats_valid(stats: &PoolStats) {
    assert!(stats.total_capacity >= stats.used_count + stats.idle_count);
    assert!(stats.avg_response_time_ms >= 0.0);
    assert!(stats.success_rate >= 0.0 && stats.success_rate <= 1.0);
}

/// 创建测试用的语言列表
pub fn test_languages() -> Vec<Language> {
    vec![
        Language::Python,
        Language::JavaScript,
        Language::Java,
        Language::Go,
        Language::Rust,
        Language::Cpp,
    ]
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_create_test_sandbox() {
        let sandbox = create_test_sandbox(Language::Python, SandboxState::Running);
        
        assert_eq!(sandbox.metadata.language, Language::Python);
        assert_eq!(sandbox.metadata.state, SandboxState::Running);
        assert_eq!(sandbox.metadata.usage_count, 0);
        assert!(!sandbox.id.is_nil());
    }

    #[test]
    fn test_create_test_pool_config() {
        let config = create_test_pool_config();
        
        assert!(config.hot_pool_max_size > 0);
        assert!(config.warm_pool_max_size > 0);
        assert!(config.cold_pool_snapshot_count > 0);
        assert!(config.max_reuse_count > 0);
        assert!(config.enable_metrics);
    }

    #[test]
    fn test_assert_sandbox_valid() {
        let sandbox = create_test_sandbox(Language::Python, SandboxState::Running);
        assert_sandbox_valid(&sandbox, &Language::Python);
    }

    #[test]
    fn test_test_languages() {
        let languages = test_languages();
        assert!(languages.len() >= 6);
        assert!(languages.contains(&Language::Python));
        assert!(languages.contains(&Language::JavaScript));
    }

    #[tokio::test]
    async fn test_wait_for_condition_success() {
        let mut counter = 0;
        let result = wait_for_condition(|| {
            let count = counter;
            counter += 1;
            async move { count >= 2 }
        }, Duration::from_millis(100)).await;
        
        assert!(result);
    }

    #[tokio::test] 
    async fn test_wait_for_condition_timeout() {
        let result = wait_for_condition(|| async { false }, Duration::from_millis(50)).await;
        assert!(!result);
    }
}